﻿using System;
using System.Numerics;
using System.Threading.Tasks;

public class AsyncMathCalculator
{
    /// <summary>
    /// 异步计算幂运算
    /// </summary>
    /// <param name="baseNumber">底数</param>
    /// <param name="exponent">指数</param>
    /// <returns>幂运算结果</returns>
    public static async Task<BigInteger> PowerAsync(double baseNumber, int exponent)
    {
        return await Task.Run(() =>
        {
            Console.WriteLine($"开始计算 {baseNumber}^{exponent}...");

            // 对于大指数运算，使用BigInteger避免溢出
            BigInteger result = 1;
            BigInteger baseBig = new BigInteger(baseNumber);

            // 使用快速幂算法提高计算效率
            for (int i = 0; i < exponent; i++)
            {
                result *= baseBig;

                // 每计算100万次报告一次进度（对于大指数）
                if (exponent > 1000000 && i % 1000000 == 0)
                {
                    double progress = (double)i / exponent * 100;
                    Console.WriteLine($"计算进度: {progress:F2}%");
                }
            }

            Console.WriteLine($"完成计算 {baseNumber}^{exponent}");
            return result;
        });
    }

    /// <summary>
    /// 优化的快速幂算法（异步版本）
    /// </summary>
    public static async Task<BigInteger> FastPowerAsync(double baseNumber, int exponent)
    {
        return await Task.Run(() =>
        {
            Console.WriteLine($"使用快速幂算法计算 {baseNumber}^{exponent}...");

            if (exponent == 0) return BigInteger.One;
            if (exponent == 1) return new BigInteger(baseNumber);

            BigInteger result = BigInteger.One;
            BigInteger current = new BigInteger(baseNumber);
            int exp = exponent;

            while (exp > 0)
            {
                if ((exp & 1) == 1) // 如果当前位为1
                {
                    result *= current;
                }
                current *= current; // 平方
                exp >>= 1; // 右移一位
            }

            Console.WriteLine($"快速幂计算完成: {baseNumber}^{exponent}");
            return result;
        });
    }

    /// <summary>
    /// 并行计算两个幂运算
    /// </summary>
    public static async Task<(BigInteger aPower, BigInteger bPower)> CalculatePowersParallelAsync(double a, double b)
    {
        Console.WriteLine($"开始并行计算: {a}^58 和 {b}^50");

        // 同时启动两个计算任务
        var taskA = FastPowerAsync(a, 58);
        var taskB = FastPowerAsync(b, 50);

        // 等待两个任务都完成
        await Task.WhenAll(taskA, taskB);

        Console.WriteLine("两个幂运算计算完成");
        return (taskA.Result, taskB.Result);
    }

    /// <summary>
    /// 计算 a^58 + b^50
    /// </summary>
    public static async Task<BigInteger> CalculateExpressionAsync(double a, double b)
    {
        try
        {
            // 验证输入范围
            if (a <= 1 || a >= 10 || b <= 1 || b >= 10)
            {
                throw new ArgumentException("a和b必须是大于1小于10的实数");
            }

            Console.WriteLine($"开始计算表达式: {a}^58 + {b}^50");
            Console.WriteLine($"输入值: a = {a}, b = {b}");

            // 并行计算两个幂
            var powers = await CalculatePowersParallelAsync(a, b);

            // 计算结果
            BigInteger result = powers.aPower + powers.bPower;

            Console.WriteLine($"计算完成: {a}^58 + {b}^50 = {result}");
            return result;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"计算过程中发生错误: {ex.Message}");
            throw;
        }
    }

    /// <summary>
    /// 批量计算多个表达式
    /// </summary>
    public static async Task<List<CalculationResult>> CalculateMultipleExpressionsAsync(List<(double a, double b)> inputs)
    {
        var tasks = inputs.Select(async input =>
        {
            try
            {
                var result = await CalculateExpressionAsync(input.a, input.b);
                return new CalculationResult
                {
                    A = input.a,
                    B = input.b,
                    Result = result,
                    Success = true
                };
            }
            catch (Exception ex)
            {
                return new CalculationResult
                {
                    A = input.a,
                    B = input.b,
                    Success = false,
                    ErrorMessage = ex.Message
                };
            }
        });

        var results = await Task.WhenAll(tasks);
        return results.ToList();
    }
}

/// <summary>
/// 计算结果类
/// </summary>
public class CalculationResult
{
    public double A { get; set; }
    public double B { get; set; }
    public BigInteger Result { get; set; }
    public bool Success { get; set; }
    public string ErrorMessage { get; set; }

    public override string ToString()
    {
        if (Success)
        {
            return $"{A}^58 + {B}^50 = {Result}";
        }
        else
        {
            return $"{A}^58 + {B}^50 计算失败: {ErrorMessage}";
        }
    }
}